﻿#pragma once

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>


#define BS_MAJOR_VERSION  1
#define BS_MINOR_VERSION  4
#define BS_PATCH_VERSION  0

#define BS_STATUS_OK             0
#define BS_STATUS_FAIL          -1
#define BS_STATUS_EXPECTED_CRLF -2
#define BS_STATUS_JOB_TOO_BIG   -3
#define BS_STATUS_DRAINING      -4
#define BS_STATUS_TIMED_OUT     -5
#define BS_STATUS_NOT_FOUND     -6
#define BS_STATUS_DEADLINE_SOON -7
#define BS_STATUS_BURIED        -8
#define BS_STATUS_NOT_IGNORED   -9

#ifdef __cplusplus
extern "C" {
#endif

typedef struct bs_job {
    int64_t id;
    char *data;
    size_t size;
} BSJ;


// optional polling call, returns 1 if the socket is ready of the rw operation specified.
// rw: 1 => read, 2 => write, 3 => read/write
// fd: file descriptor of the socket
typedef int (*bs_poll_function)(int rw, int fd,int timeout);

// export version
void bs_version(int *major, int *minor, int *patch);

// polling setup
void bs_start_polling(bs_poll_function f);
void bs_reset_polling(void);

void bs_select_polling();

// returns a descriptive text of the error code.
const char* bs_status_text(int code);

void bs_init_job(BSJ *job);
void bs_deinit_job(BSJ *job);

BSJ* bs_new_job();
void bs_free_job(BSJ *job);

// returns socket descriptor or BS_STATUS_FAIL
int bs_connect(const char *host, int port);
int bs_connect_with_timeout(const char *host, int port, float secs);

// returns job id or one of the negative failure codes.
int64_t bs_put(int fd, uint32_t priority, uint32_t delay, uint32_t ttr, const char *data, size_t bytes);

//添加的接口
int bs_call(int fd, uint32_t priority, uint32_t timeout, uint32_t ttr, const char *data, size_t bytes, BSJ *job);
int bs_reply(int fd, int64_t job, const char *data, size_t bytes);
int bs_ping(int fd);


// rest return BS_STATUS_OK or one of the failure codes.
int bs_close(int fd);
int bs_use(int fd, const char *tube);
int bs_watch(int fd, const char *tube);
int bs_ignore(int fd, const char *tube);
int bs_delete(int fd, int64_t job);
int bs_reserve(int fd, BSJ *job);
int bs_reserve_with_timeout(int fd, uint32_t ttl, BSJ *job);
int bs_release(int fd, int64_t id, uint32_t priority, uint32_t delay);
int bs_bury(int fd, int64_t id, uint32_t priority);
int bs_touch(int fd, int64_t id);
int bs_peek(int fd, int64_t id, BSJ *job);
int bs_peek_ready(int fd, BSJ *job);
int bs_peek_delayed(int fd, BSJ *job);
int bs_peek_buried(int fd, BSJ *job);
int bs_kick(int fd, int bound);
int bs_list_tube_used(int fd, char **tube);
int bs_list_tubes(int fd, char **yaml);
int bs_list_tubes_watched(int fd, char **yaml);
int bs_stats(int fd, char **yaml);
int bs_stats_job(int fd, int64_t id, char **yaml);
int bs_stats_tube(int fd, const char *tube, char **yaml);

#ifdef __cplusplus
}
#endif
